package xstring

import (
	"strings"
	"time"
)

// 时间字符串转为时间
// 为了便于其他程序处理，v0.2.50之后的版本此处返回值已调整为time.Time进行返回
// 此程序处理过程中，为了兼容尽可能多的格式，会直接将时区信息删除掉，然后使用 time.Parse 进行格式化，所以请注意时区的影响。
//
//	date	待转换的时间字符串，支持格式为Go官方支持的时间格式【此处使用循环进行批量替换的形式】
//	layout	可选参数，指定时间格式 若指定此参数则优先使用此格式进行解析
func ToTime(date string, layout ...string) time.Time {
	// 先判断有没有传入布局参数
	if len(layout) > 0 {
		for i := 0; i < len(layout); i++ {
			if tm, err := time.Parse(layout[i], date); err == nil {
				return tm
			}
		}
	}
	// 此处多添加一个datetime的转换操作，为了加速默认格式的时间转换效率
	if tm, err := time.Parse(time.DateTime, date); err == nil {
		return tm
	}
	// 字符串预处理，用于替换掉暂不支持的/、pm等字符
	date = strings.ReplaceAll(date, "\t", " ")
	if strings.Contains(date, "m") {
		date = strings.ReplaceAll(date, "pm", "PM")
		date = strings.ReplaceAll(date, "am", "AM")
	}
	if strings.Contains(date, "Z") {
		spl := strings.Split(date, "Z")
		if len(spl) == 2 && len(spl[1]) > 0 {
			date = spl[0] + "Z"
		}
	}
	date = strings.ReplaceAll(date, "_", "")
	date = strings.TrimSpace(date) // 去除两端的空格
	// 去除多余空格
	a := len(date)
	for {
		date = strings.ReplaceAll(date, "  ", " ")
		if a == len(date) {
			break
		}
		a = len(date)
	}
	// 正式时间格式化
	params := []string{
		// 常用的系统自带时间格式化格式
		time.DateTime, time.DateOnly, time.TimeOnly,
		// 常用的其他程序时间格式
		time.Layout, time.ANSIC, time.UnixDate, time.RubyDate,
		time.RFC822, time.RFC822Z, time.RFC850, time.RFC1123, time.RFC1123Z, time.RFC3339, time.RFC3339Nano,
		time.Kitchen, time.Stamp, time.StampMilli, time.StampMicro, time.StampNano,
	}
	for i := 0; i < len(params); i++ {
		if tm, err := time.Parse(params[i], date); err == nil {
			return tm
		}
	}
	// 都不在这里面的话，重新初始化分隔符，重新进行匹配
	date = strings.ReplaceAll(date, "/", "-")
	date = strings.ReplaceAll(date, " ", "")
	date = strings.ReplaceAll(date, ",", "-")
	date = strings.ReplaceAll(date, "--", "-")
	params = []string{
		// 非程序标准库中的时间格式
		"Jan-2-15:04",                    // linux系统中，ll命令输出的时间格式：Nov  9 10:28
		"2006-01-02-15:04",               // windows系统中，dir命令输出的时间格式：2024/01/19  13:31
		"Mon-02-Jan-2006-15:04:05-GMT",   // SWAGGER文档中的HEADER中的date字段返回的时间格式：Fri,19 Jan 2024 01:26:06 GMT
		"02-Jan-2006:15:04:05-0700",      // NGINX日志中的时间格式：12/Mar/2024:16:36:23+0800
		"02-Jan-2006-15:04:05",           // PHP-FPM日志默认时间格式
		"02-Jan-2006-15:04:05.000",       // PHP-FPM日志默认时间格式[毫秒]
		"02-Jan-2006-15:04:05.000000",    // PHP-FPM日志默认时间格式[微秒]
		"02-Jan-2006-15:04:05.000000000", // PHP-FPM日志默认时间格式[纳秒]
	}
	for i := 0; i < len(params); i++ {
		if tm, err := time.Parse(params[i], date); err == nil {
			return tm
		}
	}
	return time.Time{}
}
